package loja.model.conta.transacao;

import java.math.BigDecimal;
import java.util.List;

import loja.dao.DAOFactory;
import loja.dao.conta.operacao.OperacoesDAO;
import loja.model.conta.ContaAbstrata;
import loja.model.conta.operacao.Operacao;

public class Transacao {

	private DAOFactory daoFactory;
	private ContaAbstrata contaOrigem = null;
	private ContaAbstrata contaDestino = null;
	private boolean tranferencia = false;
	private String historico;
	private BigDecimal valor;

	public Transacao(DAOFactory daoFactory) {
		this.daoFactory = daoFactory;
	}

	private OperacoesDAO getOperacoesDAOContaOrigem() {
		return daoFactory.getOperacaoDAO(contaOrigem);
	}

	private OperacoesDAO getOperacoesDAOContaDestino() {
		return daoFactory.getOperacaoDAO(contaDestino);
	}

	public void setContaOrigem(ContaAbstrata contaOrigem) {
		this.contaOrigem = contaOrigem;
	}

	public void setContaDestino(ContaAbstrata contaDestino) {
		this.contaDestino = contaDestino;
	}

	public List<Operacao> listarOperacoes(ContaAbstrata conta) {
		return daoFactory.getOperacaoDAO(conta).listarOperacoes();
	}

	public BigDecimal getSaldoConta(ContaAbstrata conta) {
		return daoFactory.getOperacaoDAO(conta).getSaldoConta();

	}

	public void setTranferencia(boolean tranferencia) {
		this.tranferencia = tranferencia;
	}

	public String getHistorico() {
		return historico;
	}

	public void setHistorico(String historico) {
		this.historico = historico;
	}

	public BigDecimal getValor() {
		return valor;
	}

	public void setValor(BigDecimal valor) {
		this.valor = valor;
	}

	public void efetuarTransacao() {

		Operacao operacao = buildOperacao();

		boolean p = contaDestino != null;
		boolean q = contaOrigem != null;

		if (p || !q || this.tranferencia) {
			getOperacoesDAOContaDestino().addOperacao(operacao);
		}

		if ((p && this.tranferencia) || q) {
			Operacao operacaoInversa = (Operacao) operacao.clone();
			operacaoInversa.setValor(operacao.getValor().negate());
			getOperacoesDAOContaOrigem().addOperacao(operacaoInversa);
		}

	}

	private Operacao buildOperacao() {
		Operacao operacao = new Operacao(this.historico, this.valor);
		return operacao;
	}
}
